package com.rpinfo.editalog.util;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/**
 * Contêm diversos métodos que podem ser implementados em qualquer programa. <br/><br/>
 * São métodos para formatação, conversão, exibição de mensagens, entre outros.
 *
 * @author camilo
 */
public class Util {

  public static final int SIM = JOptionPane.YES_OPTION;
  public static final int NAO = JOptionPane.NO_OPTION;
  public static final int OK = JOptionPane.OK_OPTION;
  public static final int CANCELAR = JOptionPane.CANCEL_OPTION;
  /**
   *
   */
  public static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

  /**
   *
   * @param data
   * @return
   */
  public static String formatData(Date data) {
    String dataFormatada = sdf.format(data);
    return dataFormatada;
  }

  /**
   *
   * @param data
   * @return
   */
  public static Date parseDataSToD(String data) {
    try {
      return sdf.parse(data);
    } catch (ParseException e) {
      Util.msgErro(e, "Erro ao converter a data");
      return null;
    }
  }
  
  /**
   * Converte uma String para java.util.Date de acordo o formato indicado no parâmetro
   * @param data Valor no formato String que será convertido para o formato Data
   * @param format Pattern indicando como a data está organizada no String, para
   * "01/01/2001 23:48" o parâmetro seria "dd/MM/yyyy kk:mm"
   * @return
   */
  public static Date parseDataSToD(String data, String format) {
    try {
      SimpleDateFormat sdf2 = new SimpleDateFormat(format);
      return sdf2.parse(data);
    } catch (ParseException e) {
      Util.msgErro(e, "Erro ao converter a data");
      return null;
    }
  }

  /**
   * Retorna um String contendo a data atual do sistema no formato dd/mm/yyyy
   *
   * @return
   */
  public static String getDataAtual() {
    return formatData(new Date(System.currentTimeMillis()));
  }

  public static String formatDataStoS(String data) {
    try {
      Date dataOrig;
      String dataFormat;

      dataOrig = Util.formatData(data);
      dataFormat = Util.formatData(dataOrig);

      return dataFormat;
    } catch (ParseException e) {
      Util.msgErro(e, "Erro ao converter a data");
      return null;
    }
  }

  /**
   *
   * @param data
   * @return
   * @throws ParseException
   */
  public static Date formatData(String data) throws ParseException {
    SimpleDateFormat sdtf = new SimpleDateFormat("yyyy-MM-dd");
    Date df = sdtf.parse(data);
    return df;
  }

  /**
   * Formata número (float) com casas decimais. <br/> <b>Ex:</b> "0,00"
   *
   * @param num Número do tipo <u>Float</u>
   * @return Número (String) com casas decimais separadas por ponto
   */
  public static String formatNumSql(Float num) {
    DecimalFormat numFormat = new DecimalFormat("0.00");//cria novo objeto
    String numero = numFormat.format(num);//faz a formatação
    return numero.replaceAll(",", ".");//substitui vírgula por ponto para compatibilidade de conversão
  }

  /**
   * Seleciona o conteúdo de um JTextField
   *
   * @param jtf Objeto JTextField
   */
  public static void selJtf(JTextField jtf) {
    jtf.requestFocus();
    //    Seleciona o código de barras digitado
    jtf.setSelectionStart(0);
    jtf.setSelectionEnd(Integer.SIZE);
  }

  /**
   *
   * @param msg Texto explicativo que será exibido ao usuário
   * @return Texto inserido pelo usuário
   */
  public static String inputPesquisa(String msg) {
    return JOptionPane.showInputDialog(null, msg, "Pesquisa", JOptionPane.PLAIN_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem de erro
   *
   * @param e Objeto exception
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgErro(Exception e, String m) {
    JOptionPane.showMessageDialog(null, m + "\n\n" + e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(),
            "Não é possível continuar!", JOptionPane.ERROR_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem de erro
   *
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgErro(String m) {
    JOptionPane.showMessageDialog(null, m, "Não é possível continuar!", JOptionPane.ERROR_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir a mensagem de erro do Exception enviado como
   * parâmetro
   *
   * @param e
   */
  public static void msgErro(Exception e) {
    JOptionPane.showMessageDialog(null, e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(), "Não é possível continuar!", JOptionPane.ERROR_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem de advertência
   *
   * @param e Objeto exception
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgAdv(Exception e, String m) {
    JOptionPane.showMessageDialog(null, m + "\n\n" + e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(),
            "Atenção!", JOptionPane.WARNING_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem de advertência
   *
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgAdv(String m) {
    JOptionPane.showMessageDialog(null, m, "Atenção!", JOptionPane.WARNING_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir a mensagem de advertência gerada pelo Exception
   *
   * @param e
   */
  public static void msgAdv(Exception e) {
    JOptionPane.showMessageDialog(null, e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(), "Atenção!", JOptionPane.WARNING_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma informação
   *
   * @param e Objeto exception
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgInfo(Exception e, String m) {
    JOptionPane.showMessageDialog(null, m + "\n\n" + e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(),
            "", JOptionPane.INFORMATION_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma informação
   *
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msgInfo(String m) {
    JOptionPane.showMessageDialog(null, m, "", JOptionPane.INFORMATION_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir a informação gerada pelo Exception
   *
   * @param e
   */
  public static void msgInfo(Exception e) {
    JOptionPane.showMessageDialog(null, e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(), "", JOptionPane.INFORMATION_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem
   *
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msg(String m) {
    JOptionPane.showMessageDialog(null, m, "", JOptionPane.PLAIN_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir a mensagem gerada pelo Exception
   *
   * @param e
   */
  public static void msg(Exception e) {
    JOptionPane.showMessageDialog(null, e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(), "", JOptionPane.PLAIN_MESSAGE);
  }

  /**
   * Aciona um JOptionPane configurado para exibir uma mensagem.
   *
   * @param e Objeto exception
   * @param m Mensagem adicional. Se não houver, inserir string vazia
   */
  public static void msg(Exception e, String m) {
    JOptionPane.showMessageDialog(null, m + "\n\n" + e.getMessage()
            + "\n\nDetalhes\n" + e.getCause(),
            "", JOptionPane.PLAIN_MESSAGE);
  }

  /**
   * Exibe uma janela solicitando a decisão (sim/não) do usuário
   *
   * @param question Pergunta que será exibida ao usuário
   * @param title Título da JOptionPane
   * @return Retorna int para saber se o usuário clicou em sim ou não
   */
  public static int confirm(String question, String title) {
    return JOptionPane.showConfirmDialog(null, question, title,
            JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
  }

  public static String setFirstLetterUpperCase(String str, boolean delUltSpace) {
    if (!str.isEmpty()) {
      StringBuilder sbuf = new StringBuilder();
//    O texto é dividido palavra por palavra, usando o "espaço" como referência
      String tmp[] = str.split(" ");
//    Laço para tratamento de cada palavra do array
      for (int i = 0; i < tmp.length; i++) {
        tmp[i] = tmp[i].toLowerCase();
        if ((tmp[i].length() > 2 //Se a palavra possuir mais do que dois Characters ela terá a primeira letra Maiúscula
                && tmp[i].substring(0, 1).matches("[A-Za-z]"))//E se o primeiro Character for uma letra
                || (tmp[i].length() <= 2 && i == 0)) { //OU se for a primeira palavra e possuir até dois caracteres
          sbuf.append(tmp[i].replaceFirst(tmp[i].substring(0, 1), tmp[i].substring(0, 1).toUpperCase()));
        } else {
          sbuf.append(tmp[i]);
        }
        sbuf.append(" ");// Acrescenta o espaço entre cada palavra
      }
      if (delUltSpace) {
        str = sbuf.substring(0, sbuf.length() - 1);//Elimina o espaço do final do texto
      } else {
        str = sbuf.toString();
      }
      return str;
    }
    return str;
  }

  public static void setFirstLetterUpperCase(JTextField str) {
    str.setText(Util.setFirstLetterUpperCase(str.getText(), true));
  }

  /**
   * Transforma em maiúscula a primeira letra das palavras numa String
   *
   * @param str JTextField que possui a String a ser formatada
   * @param position Posição atual do cursor no JTextField <i>(use getSelectionStart())</i>
   */
  public static void setFirstLetterUpperCase(JTextField str, int position) {
    if (str.getText().endsWith(" ")
            && str.getText().length() == position) {
      str.setText(Util.setFirstLetterUpperCase(str.getText(), false));
    } else {
      str.setText(Util.setFirstLetterUpperCase(str.getText(), true));
    }
    str.setSelectionStart(position);
    str.setSelectionEnd(position);
  }

  public static String formatTelefone(String telefone) throws UtilException {
    final String regraTelefone = ".[0-9]{2}. [0-9]{4,5}-[0-9]{4}";
    final String regra0800 = "[0-9]{4} [0-9]{3} [0-9]{4}";

    if (telefone.matches(regraTelefone) || telefone.matches(regra0800)) {
      System.out.println("telefone <" + telefone + "> correto");
    } else if ((telefone.length() == 10 || telefone.length() == 11)
            && !telefone.startsWith("0800")) {
      StringBuilder sb = new StringBuilder();
      sb.append(telefone);
      sb.insert(0, "(");
      sb.insert(3, ") ");
      if (telefone.length() == 10) {
        sb.insert(9, "-");
      } else {
        sb.insert(10, "-");
      }
      telefone = sb.toString();
    } else if (telefone.startsWith("0800") && telefone.length() == 11) {
      StringBuilder sb = new StringBuilder();
      sb.append(telefone);
      sb.insert(4, " ");
      sb.insert(8, " ");
      telefone = sb.toString();
    } else {
      throw new UtilException("numero de telefone inválido. Formatos válidos: \n\n"
              + "-(99) 9999-9999\n- (99) 99999-9999\n- 0800 999 9999");
    }
    return telefone;
  }

  public class ValidaDigitacaoData extends PlainDocument {

    public static final int POSICAO_PRIMEIRA_BARRA = 2;
    public static final int POSICAO_SEGUNDA_BARRA = 5;
    public static final int POSICAO_FINAL = 9;

    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
      if (str == null) {
        return;
      }

      if (offs == POSICAO_PRIMEIRA_BARRA || offs == POSICAO_SEGUNDA_BARRA) {
        if (!str.matches("[/]{" + str.length() + "}")) {
          str = "/" + str;
        }
      } else if (offs > POSICAO_FINAL) {//se maior que nove excede o padrão de caracteres para data
        return;
      } else {
        if (!str.matches("[0-9() -]{" + str.length() + "}")) {
          return;
        }
      }
      super.insertString(offs, str, a); //To change body of generated methods, choose Tools | Templates.
    }
  }

  public class SomenteNumeros extends PlainDocument {

    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
      if (str == null) {
        return;
      }

      /*for (int i = 0; i < str.length(); i++) {
       if (Character.isDigit(str.charAt(i)) == false) {
       return;
       }
       }*/
      if (!str.matches("[0-9() -]{" + str.length() + "}")) {
        return;
      }
      super.insertString(offs, str, a);
    }
  }

  public static String getPasswordJpf(JPasswordField jPass) {
    StringBuilder build = new StringBuilder();
    for (char pass : jPass.getPassword()) {
      build.append(pass);
    }
    return build.toString();
  }
}
